
/*********************************  COPYRIGHT 2015 --------  *********  BEGIN OF FILE  ********************************/

/**********************************************************************
* @file           : padc.c
* @author         : --
* @version        : --
* @date           : 2015-07-20
* @brief          : padc program body
* @Description    : --
**********************************************************************/

/* Includes  == 文件包含 --------------------------------------------*/
#include "padc.h"



/* Private typedef    ==  私有类型 ----------------------------------*/
/* Private define     ==  私有定义 ----------------------------------*/
#define	PADC_GPIO              GPIOC
#define	PADC_PIN               GPIO_Pin_0
#define	PADC_CLK               RCC_APB2Periph_GPIOC
#define	PADC_GPIO1              GPIOC
#define	PADC_PIN1               GPIO_Pin_5
#define	PADC_CLK1               RCC_APB2Periph_GPIOC

#define	PADC_ADC_NUM           ADC1
#define	PADC_ADC_CLK           RCC_APB2Periph_ADC1
#define	PADC_CHANNEL           ADC_Channel_10
#define	PADC_ADC_CLK1           RCC_APB2Periph_ADC1
#define	PADC_CHANNEL1           ADC_Channel_15

#define PADC_BIT_SCALE         (float)(0.000244140625f)  // 1 / 4096, ADC分辨率为12位
#define PADC_SCALE             (float)(11.0f)            // (47K + 4.7K) / 4.7K, 电源电压分压值, 总电阻/分压电阻
#define PADC_REFER_VOL         (float)(3.3f)             // AD参考电压
#define PADC_DATA_BUFFLEN      (u8)(10)                  // 定义ADC保存数据缓存大小
#define PADC_R1             (float)(120.0f)            // 接地电阻
#define PADC_R2             (float)(2.0f)            // 
#define PADC_REF            ((float)(0.05f) *25)           //电流采样电阻
#define ENLARGE								25											//差分放大器发大倍数

#define TEMPSATE						((float)4600/4095)
#define TEMPSATE_D					500
	
#define TempSafeMin     500			//50℃
#define TempSafeMax     5100			//510℃
#define TempSafe_A			40000/(TempSafeMax - TempSafeMin)

vu16  AD1_Value[AD_SAMPLE_TIMES][AD1_CHNNEL_CNT];   //用来存放ADC转换结果，也是DMA的目标地址 
vu16  AD1_After_filter[AD1_CHNNEL_CNT];    //用来存放求平均值之后的结果 



/* Private macro      ==  私有宏 ------------------------------------*/
/* Private variables  ==  私有变量 ----------------------------------*/
s16 PADC_DataBuff[PADC_DATA_BUFFLEN] = {0};

void DMA_Configuration(void);

/* Private functions  ==  私有函数定义 ------------------------------*/

/**********************************************************************
* @Brief   : None
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
void PADC_Init(void)
{
	PADC_GPIO_Config();
	DMA_Configuration();
	PADC_Config();
}



/**********************************************************************
* @Brief   : None
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
void PADC_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(PADC_CLK, ENABLE);
	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;		

	GPIO_InitStructure.GPIO_Pin = PADC_PIN | PADC_PIN1;
	GPIO_Init(PADC_GPIO, &GPIO_InitStructure); 	
}



/**********************************************************************
* @Brief   : None
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
void PADC_Config(void)
{
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(PADC_ADC_CLK,ENABLE); 

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel = AD1_CHNNEL_CNT;
	ADC_Init(PADC_ADC_NUM, &ADC_InitStructure);
	
	ADC_RegularChannelConfig(PADC_ADC_NUM, PADC_CHANNEL, 1, ADC_SampleTime_28Cycles5);
	ADC_RegularChannelConfig(PADC_ADC_NUM, PADC_CHANNEL1, 2, ADC_SampleTime_28Cycles5);
	
	// 开启ADC的DMA支持（要实现DMA功能，还需独立配置DMA通道等参数）     
  ADC_DMACmd(ADC1, ENABLE);      /* Enable ADC1 */ 
	ADC_Cmd(PADC_ADC_NUM, ENABLE);
	
	ADC_ResetCalibration(PADC_ADC_NUM);
	while(ADC_GetResetCalibrationStatus(PADC_ADC_NUM));
	ADC_StartCalibration(PADC_ADC_NUM);
	while(ADC_GetCalibrationStatus(PADC_ADC_NUM));
	
	ADC_SoftwareStartConvCmd(PADC_ADC_NUM, ENABLE);

  DMA_Cmd(DMA1_Channel1, ENABLE);  //启动DMA通道  
}



/**********************************************************************
* @Brief   : 计算电机采样电阻的电压
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
float PADC_GetVol(void)
{
//	u8 i;
	float Precent, voltage;
//  s32 sum;
//	s16 adc;
	
	// 更新ADC数据缓存
//	sum = 0;
//	for(i=0; i<(PADC_DATA_BUFFLEN - 1); i++)
//	{
//		PADC_DataBuff[i] = PADC_DataBuff[i+1];
//		sum += PADC_DataBuff[i];
//	}
//	PADC_DataBuff[PADC_DATA_BUFFLEN - 1] = (s16)ADC_GetConversionValue(PADC_ADC_NUM);
//	sum += PADC_DataBuff[PADC_DATA_BUFFLEN - 1];
//	adc = (s16)(sum / PADC_DATA_BUFFLEN);      // 取平均
	
	Precent = (float)AD1_After_filter[1] * PADC_BIT_SCALE;	        // 算出与参考电压的百分比
	voltage = Precent * PADC_REFER_VOL;	          								  // 计算实际电压，3.3V为参考电压
//	voltage = voltage * (1 + PADC_R1 / PADC_R2);  	                // 计算电源电压值 
	voltage /= PADC_REF;
	
	return voltage;
}

/**********************************************************************
* @Brief   : 计算安全温度值
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
s16 Get_Safe_Temp(void)
{
	return (TEMPSATE * AD1_After_filter[0] + TEMPSATE_D);
}

/**********************************************************************
* @Brief   : DMA初始化
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
void DMA_Configuration(void)  
{  /* ADC1  DMA1 Channel Config */  
 DMA_InitTypeDef DMA_InitStructure;  
 DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值    
 DMA_InitStructure.DMA_PeripheralBaseAddr =  (u32)&ADC1->DR;  //DMA外设ADC基地 址  
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD1_Value;  //DMA内存基地址  
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //内存作为数据传输的目的地  
 DMA_InitStructure.DMA_BufferSize = AD_SAMPLE_TIMES*AD1_CHNNEL_CNT;  //DMA通道的DMA缓存的大小    
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器 不变  
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增  
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位 
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度 为16位  
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环缓存模式  
 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级   
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输  
 DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道   
}

/**********************************************************************
* @Brief   : 计算算术平均值
* @Input   : None
* @Output  : None
* @Return  : None
* @Remark  : None
**********************************************************************/
 void Adc_filter(void) 
{ 
  u16  sum = 0; 
	u8  count,i;         
	for(i=0;i<AD1_CHNNEL_CNT;i++)         
	{            
		for ( count=0;count<AD_SAMPLE_TIMES;count++)             
		{              
			sum += AD1_Value[count][i];             
		}              
		AD1_After_filter[i]=sum/AD_SAMPLE_TIMES;             
		sum=0;       
	}   	  
}

/*********************************  COPYRIGHT 2015 --------  *********  END OF FILE  **********************************/
